package design.patterns.behavioral;

/**
 * 访问者模式
 * 解释：
 * 访问者模式是一种行为设计模式， 它能将算法与其所作用的对象隔离开来。
 *
 *
 */

/**
 * 情景
 * 监控  系统 的硬盘读写 和 CPU的状态
 *
 * 系统 通过 Vistor 访问 硬盘 和 CPU 的状态
 */
public class J_Vistor {
    public static void main(String[] args) {
        /* 1. 创建系统，系统中包含 CPU 和 硬盘 */
        MySystem mySystem = new MySystem(new CPU(), new HardDisk());

        /* 2. 创建访问访问类 */
        MyVisitor myVisitor = new MyVisitor();

        /* 3. 监控系统状态*/
        while (true){
            mySystem.monitor(myVisitor);
            Sleep.sleep(1000);

        }
    }
}

/**-----
 * 主要类
 * 访问类（MyVisitor） ：用于获取CPU 和 硬盘 信息
 *
 */

/**
 * 访问者接口
 * 功能：用于显示收集的信息
 */
interface Visitor{
    /* 监控硬盘 */
    void monitorHardDisk(HardDisk hardDisk);
    /* 监控CPU */
    void monitorCPU(CPU cpu);
}

/**
 * 监控接口
 */
interface Monitor {

    /**
     * 用于暴露自己的类
     * @param visitor
     */
    void monitor(Visitor visitor);
}

/**
 * CPU类
 * 实现了监控接口
 */
class CPU implements Monitor{

    /**
     * 记录CPU的状态
     */
    private String state="0";


    {// 修改CPU的状态
        new Thread(()->{
            while (true){
                Sleep.sleep(500);
                this.state = String.valueOf(Math.random()*10);
            }
        }).start();
    }
    @Override
    public void monitor(Visitor visitor) {
        visitor.monitorCPU(this);
    }

    public String getState() {
        return state;
    }
}

/**
 * 硬盘类
 * 实现了监控接口
 */
class HardDisk implements Monitor{
    /**
     * 记录硬盘的状态
     */
    private String state="0";

    {// 修改硬盘的状态
        new Thread(()->{
            while (true){
                Sleep.sleep(500);
                this.state = String.valueOf(Math.random()*10);
            }
        }).start();
    }
    @Override
    public void monitor(Visitor visitor) {
        visitor.monitorHardDisk(this);
    }

    public String getState() {
        return state;
    }
}

/**
 * 系统类
 * 系统类中包含：
 *          CPU
 *          硬盘
 */
class MySystem implements Monitor{
    private CPU cpu;
    private HardDisk hardDisk;

    public MySystem(CPU cpu, HardDisk hardDisk) {
        this.cpu = cpu;
        this.hardDisk = hardDisk;
    }

    @Override
    public void monitor(Visitor visitor) {
        cpu.monitor(visitor);
        hardDisk.monitor(visitor);
    }
}
class MyVisitor implements Visitor{

    /**
     * 监控硬盘
     * @param hardDisk
     */
    @Override
    public void monitorHardDisk(HardDisk hardDisk) {
        System.out.println("硬盘："+hardDisk.getState());
    }


    /**
     * 监控 CPU
     * @param cpu
     */
    @Override
    public void monitorCPU(CPU cpu) {
        System.out.println("CPU "+cpu.getState());
    }
}

/**
 * 睡眠类
 * 线程的睡眠
 */
class Sleep{
    static void sleep(long millis){
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}